home *** CD-ROM | disk | FTP | other *** search
- -> FILE: ESrc:Own/loadppclib.e REV: 1 --- load ppc.library on BlizzPPC
- /* History
- 0 Started in September 2000.
- 1 2nd Sep: added WOS termination. added retry.
- */
-
- OPT PREPROCESS
-
- #define VERSION 'loadppclib 1.0.0 (2.9.2000)'
- #define LIBNAME 'ppc.library'
-
- MODULE 'dos/dos','dos/doshunks','exec/memory','exec/execbase',
- 'graphics/gfxbase','exec/libraries','exec/resident',
- 'exec/execbase'
-
- ENUM ARG_LIB,ARG_FORCE,NUMARGS
-
- ENUM ER_OK,ER_PARAM,ER_NOMEM,ER_ALREADY,ER_NOBPPC,ER_NO0X0LIB,ER_WOS,
- ER_LOADSEG,ER_NOTLIB,ER_NOTPPCLIB,ER_EMULLIB,ER_ADDPPCLIB
-
- DEF array[NUMARGS]:ARRAY OF LONG
-
- PROC main() HANDLE
- DEF attnflags
- DEF rdargs = NIL, name:PTR TO CHAR, ioerr, ret
- DEF r, pname[64]:STRING
- DEF wosbase = NIL:PTR TO lib, wosb, da0x0lib
- DEF seglist = NIL, ids
-
- IF (KickVersion(37) = 0)
- WriteF('This program requires AmigaOS 2.04+\n')
- RETURN RETURN_FAIL
- ENDIF
-
- attnflags := extattnflags(Int(execbase + $128))
- IF ((attnflags AND AFF_68040) = 0)
- PrintF('This program requires 68040+ CPU\n')
- RETURN RETURN_FAIL
- ENDIF
-
- -> test if it's there already...
- Forbid()
- ids := FindName(execbase + 378, LIBNAME)
- Permit()
- IF (ids) THEN Raise(ER_ALREADY)
-
- FOR r := 0 TO NUMARGS-1; array[r] := 0; ENDFOR
- IF ((rdargs := ReadArgs('LIBRARY,FORCE/S',
- array, NIL)) = NIL) THEN Raise(ER_PARAM)
-
- IF (array[ARG_LIB])
- name := array[ARG_LIB]
- ELSE
- name := 'libs:' + LIBNAME
- ENDIF
-
- -> see if the HW is there...
- Forbid()
- da0x0lib := FindName(execbase + 378,
- IF (attnflags AND $80) THEN '68060.library' ELSE '68040.library')
- ids := FindResident('BlizzardPPC.IDTag')
- wosb := FindName(execbase + 378, 'powerpc.library')
- Permit()
- IF ((ids = NIL) AND (array[ARG_FORCE] = 0)) THEN Raise(ER_NOBPPC)
- IF (da0x0lib = NIL) THEN Raise(ER_NO0X0LIB)
-
- IF (wosb)
- IF (wosbase := OpenLibrary('powerpc.library', 14))
- IF (array[ARG_FORCE] = 0) THEN Raise(ER_WOS)
- ENDIF
- ENDIF
-
- -> load the seglist
- IF ((seglist := LoadSeg(name)) = NIL) THEN Raise(ER_LOADSEG)
- IF (initseg({seglist}))
- UnLoadSeg(seglist)
-
- -> retry, it seems to fail sometimes...
- IF ((seglist := LoadSeg(name)) = NIL) THEN Raise(ER_LOADSEG)
- IF (initseg({seglist})) THEN Raise(ER_ADDPPCLIB)
- ENDIF
-
- -> succeeded & got wosbase?
- IF ((seglist = NIL) AND (wosbase <> NIL))
-
- IF ((r := AllocMem(8, MEMF_PUBLIC)) = NIL) THEN Raise(ER_NOMEM)
-
- -> patch LIB_OPEN to return zero.
- Forbid()
- PutLong(r, $70004E75) -> moveq #0,d0 / rts
- PutLong(r + 4, SetFunction(wosbase, -$6, r))
- CacheClearU()
- Permit()
- ENDIF
-
- EXCEPT DO
- IF (exception)
- IF (ioerr := IoErr()) THEN PrintFault(ioerr, NIL)
- GetProgramName(pname, StrMax(pname) - 1)
- PrintF('\s: \s\s\n', pname,
- ListItem(['', 'argument error',
- 'no memory',
- 'library already in memory',
- 'Blizzard PPC not found, FORCE to override',
- '680x0.library not loaded',
- 'WarpUP found in memory, FORCE to override',
- 'could not loadseg', 'file is not a library',
- 'file is not a ',
- 'file is a ppclibemu ',
- 'could not add '
- ], exception),
- IF ((exception = ER_NOTLIB) OR (exception = ER_NOTPPCLIB) OR
- (exception = ER_EMULLIB)) THEN LIBNAME ELSE ''
- )
- ret := RETURN_ERROR
- ELSE
- ret := RETURN_OK
- ENDIF
-
- IF (seglist) THEN UnLoadSeg(seglist)
- IF (wosbase) THEN CloseLibrary(wosbase)
- IF (rdargs) THEN FreeArgs(rdargs)
- ENDPROC ret
-
- CHAR '$VER: ',VERSION,0
-
-
- PROC initseg(seglist:PTR TO LONG)
- DEF r, segment:PTR TO LONG, tag:PTR TO rt, seglen
- DEF ids, emul = 0, islibrary = 0, isthelib = 0
-
- -> do the stuff in forbid...
- Forbid()
- IF (FindName(execbase + 378, LIBNAME) = NIL)
-
- -> find the ROMTag in seglist
- segment := ^seglist * 4
-
- WHILE (^seglist <> NIL) AND (segment <> NIL)
-
- seglen := segment[-1] - 8 - SIZEOF rt
- tag := segment + 2
-
- WHILE (^seglist <> NIL) AND (seglen > 0)
-
- ADDQ.L #2,tag
- SUBQ.L #2,seglen
-
- IF ((tag.matchword = RTC_MATCHWORD) AND
- (tag.matchtag) = tag)
-
- islibrary := 1
-
- -> check name
- IF (StrCmp(tag.name, LIBNAME))
-
- isthelib := 1
-
- -> check for ppclibemu
- IF (ids := tag.idstring)
- FOR r := 24 TO StrLen(ids) - 8
- IF (StrCmp(ids + r, 'mulation', STRLEN))
- emul := 1
- ENDIF
- ENDFOR
- ENDIF
-
- IF (emul = 0)
- -> init the resident.
- -> NOTE: emulates ROM-init with seglist = NIL
- InitResident(tag, NIL)
-
- -> did it work?
- IF (FindName(execbase + 378, LIBNAME))
- -> success! prevent unloading
- ^seglist := NIL
- ENDIF
- ENDIF
- ENDIF
- ENDIF
- ENDWHILE
- segment := segment[] * 4
- ENDWHILE
- ENDIF
-
- Permit()
-
- IF (^seglist)
- IF (islibrary = 0) THEN Raise(ER_NOTLIB)
- IF (isthelib = 0) THEN Raise(ER_NOTPPCLIB)
- IF (emul) THEN Raise(ER_EMULLIB)
- ENDIF
- ENDPROC ^seglist
-
- PROC extattnflags(flags)
- DEF orren = 0
- IF ((flags AND AFF_68040) AND ((flags AND $80) = 0))
- MOVE.L A5,-(A7)
- LEA check060(PC),A5
- JSR -$78(A6)
- JSR -$1E(A6)
- JSR -$7E(A6)
- MOVE.L (A7)+,A5
- MOVE.L D0,orren
- ENDIF
- RETURN flags OR orren
-
- check060:
- INT $4E7A,$8801 -> MOVEC VBR,A0
- MOVE.L $10(A0),-(A7)
- MOVE.L $2C(A0),-(A7)
- MOVE.L A0,-(A7)
- LEA c060illegal(PC),A1
- MOVE.L A1,$10(A0)
- MOVE.L A1,$2C(A0)
- INT $F518,$F4F8,$F4D8
-
- MOVEQ #0,D0
-
- INT $4E7A,$0008 -> MOVEC BUSCR,D0
- INT $4E7A,$0808 -> MOVEC PCR,D0
-
- NOP
- NOP
- MOVEQ #1,D0
-
- c060exit_illegal:
- MOVE.L (A7)+,A0
- MOVE.L (A7)+,$2C(A0)
- MOVE.L (A7)+,$10(A0)
- INT $F518,$F4F8,$F4D8
- TST.L D0
- BEQ.S c060_no060
-
- MOVE.L #$00000080,D0
-
- c060_no060:
- NOP
- RTE
-
- c060illegal:
- LEA c060exit_illegal(PC),A0
- MOVE.L A0,2(A7)
- NOP
- RTE
- ENDPROC
-